#include "client.h"

net_tcp::client::client(asio::io_context& context) :m_context(std::move(context)), m_resolver(context)
{
	m_session = std::shared_ptr<session>(new session(context));
	m_session->regist_on_close(std::bind(&client::on_disconnected, this));
	m_session->regist_on_recv(std::bind(&client::on_recv, this));
	m_session->regist_on_error(std::bind(&client::on_error, this));
}

int net_tcp::client::get_id()
{
	return  m_session->ID();
}

bool net_tcp::client::connect(const char* ip, int port)
{
	m_ip_str = ip;
	m_port_str = std::to_string(port);
	return re_connect();
}

bool net_tcp::client::re_connect()
{
	if (!m_session->get_socket().is_open())
	{
		asio::ip::tcp::resolver::query query(m_ip_str, m_port_str);
		m_resolver.async_resolve(query, [this](const asio::error_code& error, asio::ip::tcp::resolver::iterator it)->void {
			if (!error)
			{
				m_session->get_socket().async_connect(it->endpoint(), [this](asio::error_code error)->void {
					if (error)
					{
						m_session->set_last_error(error);
						on_error();
					}
					else {
						on_connected();
						m_session->read_loop();
					}
					});
			}
			else {
				m_session->set_last_error(error);
				on_error();
			}
			});
		return true;
	}
	else {
		return false;
	}
}

bool net_tcp::client::send(const char* data, int len)
{
	if (m_session.use_count() <= 0)
		return false;

	return m_session->send(data, len);
}

bool net_tcp::client::send(std::string data)
{
	return send(data.c_str(), data.length());
}

void net_tcp::client::close()
{
	m_session->close();
}